package com.af.dao.flight.impl;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import java.util.List;

import com.af.common.CommonUtil;
import com.af.common.DBHelper;
import com.af.common.GlobalVariables;
import com.af.common.Log4jXmlConfig;
import com.af.common.PropertiesManager;
import com.af.common.SmsSendService;
import com.af.dao.flight.IFlightNotice;
import com.af.dao.pay.IPayToApi;
import com.af.dao.pay.PayEntity;
import com.af.dao.pay.impl.PayToApi;
import com.af.entity.flight.FlightOrder;
import com.af.entity.flight.Itinerary;
import com.af.entity.flight.OrderTicket;

public class FlightNotice implements IFlightNotice {

	Logger LOG = Log4jXmlConfig.getInstance().returnLogger(FlightNotice.class);

	@Override
	public void changeSignNotify(Map map) {
		// TODO Auto-generated method stub

	}

	/**
	 * 添加退款记录
	 * @param map
	 * @param poundage
	 * @param realyMoney
	 */
	private void addRefundNotice(Map map,double poundage,double realyMoney) {
		String sql = "{call addRefundNotice(?,?,?,?,?,?,?,?)}";

		Object[] args = new Object[8];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");

		args[2] = map.get("status");

		args[3] = map.get("amount");

		args[4] = map.get("isOnline");

		args[5] = returnOrderDesc(map.get("orderNo").toString(), "退款金额"
				+ map.get("amount").toString());

		args[6] = poundage;
		
		args[7] = realyMoney;

		update(sql, args);
	}

	/**
	 * 退款
	 */
	@Override
	public void orderRefund(Map map) {
		// TODO Auto-generated method stub

		String orderId = map.get("orderNo").toString();

		String status = map.get("status").toString();

		// 退款金额
		double amount = Double.parseDouble(map.get("amount").toString());

		// 是否在线退款[0:线下,1:线上]
		String isOnline = map.get("isOnline").toString();

		if (isOnline.equals("1")) {

			IPayToApi aliPay = new PayToApi();

			PayEntity pe = new PayEntity();

			pe.setOrderid(orderId);

			FlightOrder fo = getFlightOrder(orderId);


			double payTotal = Double.parseDouble(fo.getPayTotal().toString());
			
			double poundage = 0, refund = 0, comapre=(int) (payTotal / amount), orderTotal = Double.parseDouble(fo
					.getOrderTotal().toString());
			
			if(CommonUtil.isNotNullOrEmpty(fo.getTicketNo())){
				double treadFee = Double.parseDouble(CommonUtil.isNotNullOrEmpty(fo.getTradingfee().toString())?fo.getTradingfee().toString():"0");
				orderTotal = orderTotal - treadFee;
				payTotal = payTotal - treadFee;
			}
			
			if(fo.getPassengers().toString().contains("|")){
				refund = new BigDecimal(orderTotal/payTotal*amount).setScale(0,BigDecimal.ROUND_HALF_UP).doubleValue();
			}else{
				refund = orderTotal-(payTotal-amount);
			}
			
			
			
			addRefundNotice(map,poundage,refund);
			
			pe.setTot_trans_amt(returnRefundTotal(refund));

			pe.setSub_order_flag("N");
			
			pe.setSeller_id(GlobalVariables.FLIGHT_SELLER_ID);

			pe.setSub_order_num(0);

			pe.setBuyer_id(fo.getMemberNum().toString());

			pe.setOrder_desc(returnOrderDesc(orderId, "退款金额" + refund));

			pe.setNotify_url(PropertiesManager.getInstance().returnValue(
					"PAY_FLIGHT_NOTICE"));

			aliPay.REFUND(pe);

		}

	}

	private String returnOrderDesc(String orderId, String desc) {
		return new StringBuffer("[").append(orderId).append("]").append(desc)
				.toString();
	}

	/**
	 * 精确金额到分，取整数
	 * 
	 * @param amt
	 * @return
	 */
	private int returnRefundTotal(double amt) {

		int refund = (int) (amt * 100);

		return refund;

	}

	/**
	 * 出票
	 */
	@Override
	public void orderTicket(Map map) {
		// TODO Auto-generated method stub
		// 添加新出票通知记录

		String sql = "{call addOrderTicket(?,?,?,?)}";

		Object[] args = new Object[4];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");
		try {
			args[2] = new String(map.get("passengers").toString().getBytes(
					"ISO-8859-1"), "GBK");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		args[3] = map.get("ticketsNo");

		update(sql, args);
		
		FlightOrder fo = getFlightOrder(map.get("orderNo").toString());
		
//		addPassengerItin(fo);

		OrderTicket ot = null;
		
		List<OrderTicket> orderTickets = new ArrayList<OrderTicket>();
		if (args[3].toString().contains("^") == true) {
			String[] passenger = args[2].toString().split("\\^");
			String[] ticketsNo = args[3].toString().split("\\^");
			for (int i = 0; i < ticketsNo.length; i++) {
				ot = new OrderTicket();
				ot.setPassengerName(passenger[i]);
				ot.setTicketNo(ticketsNo[i]);
				orderTickets.add(ot);
			}
		} else {
			ot = new OrderTicket();
			ot.setPassengerName(args[2].toString());
			ot.setTicketNo(args[3].toString());
			orderTickets.add(ot);
		}
		fo.setOrderTickets(orderTickets);
		LOG.info("出票通知短信发送：" + JSONObject.fromObject(fo) + ","
				+ args[3].toString() + args[3].toString().contains("^"));
		sendOrderSms(fo);

	}

	// 发送出票短信
	public void sendOrderSms(FlightOrder fo) {

		for (int i = 0; i < fo.getOrderTickets().size(); i++) {
			OrderTicket ot = fo.getOrderTickets().get(i);
			String content = new StringBuffer().append(
					CommonUtil.returnShortDateTime(fo.getSdate().toString(),
							"yy/MM/dd")).append("从").append(fo.getScity())
					.append("[").append(
							CommonUtil.returnShortDateTime(fo.getDepTime()
									.toString(), "HH:mm")).append("]").append(
							"飞往").append(fo.getEcity()).append("的航班[").append(
							fo.getFlightNo()).append("]").append("出票成功,票号[")
					.append(ot.getTicketNo()).append("],PNR[").append(
							fo.getPnrNo()).append("]").toString();
			int sendcode = new SmsSendService().sendSms(fo.getPhoneNum()
					.toString(), content, "出票短信通知");
			LOG.info(new StringBuffer("订单编号：").append(fo.getOrderNo()).append(
					"出票通知,票号：").append(fo.getTicketNo()).append("短信通知状态：")
					.append(sendcode).toString());
		}

	}

	// 发送换编码短信
	private void sendChangePnrSms(FlightOrder fo, String pnr) {
		String content = new StringBuffer(CommonUtil.returnShortDateTime(fo
				.getSdate().toString(), "yyyy-MM-dd")).append("从").append(
				fo.getScity()).append("的航班[").append(fo.getFlightNo()).append(
				"]").append("换编码成功,原编码[").append(fo.getPnrNo())
				.append("]新编码号[").append(pnr).append("]").toString();

		int sendcode = new SmsSendService().sendSms(
				fo.getPhoneNum().toString(), content, "换编码短信通知");

		LOG.info(new StringBuffer("订单编号：").append(fo.getOrderNo()).append(
				"换编码成功,票号：").append(pnr).append("短信通知状态：").append(sendcode)
				.toString());
	}

	// 暂不能出票
	@Override
	public void remarkNotify(Map map) {
		// TODO Auto-generated method stub
		String sql = "{call addRemarkNotify(?,?,?,?)}";

		Object[] args = new Object[4];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");

		args[2] = map.get("remarkType");

		if (CommonUtil.isNotNullOrEmpty(map.get("remarks"))) {
			try {
				args[3] = new String(map.get("remarks").toString().getBytes(
						"ISO-8859-1"), "GBK");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				LOG.error("Exception in remarkNotify "
						+ JSONObject.fromObject(map), e);
			}
		} else {
			args[3] = "";
		}
		update(sql, args);

	}

	/**
	 * 修改票号
	 */
	@Override
	public void updateTickets(Map map) {
		// TODO Auto-generated method stub
		String sql = "{call updateTickets(?,?,?)}";

		Object[] args = new Object[4];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");

		args[2] = map.get("passengers");

		args[3] = map.get("ticketsNo");

		update(sql, args);
	}

	/**
	 * 换编码
	 * 
	 * @param map
	 */
	public void changePnrNotify(Map map) {

		String sql = "{call addChangePnrNotify(?,?,?)}";

		Object[] args = new Object[3];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");

		args[2] = map.get("pnr");

		update(sql, args);

		FlightOrder fo = getFlightOrder(map.get("orderNo").toString());

		sendChangePnrSms(fo, map.get("pnr").toString());

	}

	/**
	 * 获取行程单信息
	 * 
	 * @param itineraryNo
	 * @return
	 */
	public Itinerary getItineray(String itineraryNo) {

		Itinerary itin = null;
		String sql = new StringBuffer(
				"SELECT * FROM Plan_Itinerary WITH(NOLOCK) WHERE 1=1 AND itineraryNo='")
				.append(itineraryNo).append("'").toString();
		DBHelper dh = DBHelper.getInstance();

		try {
			dh.setBeanClass(Itinerary.class);
			itin = (Itinerary) dh.query(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		dh.close();
		return itin;
	}

	/**
	 * 获取机票订单信息
	 * 
	 * @param orderid
	 * @return
	 */
	public FlightOrder getFlightOrder(String orderid) {

		FlightOrder fo = null;

		String sql = new StringBuffer(
				"SELECT * FROM Plane_Order WITH(NOLOCK) WHERE OrderNo='").append(orderid)
				.append("'").toString();
		try {
			DBHelper dh = DBHelper.getInstance();

			dh.setBeanClass(FlightOrder.class);

			fo = (FlightOrder) dh.query(sql);

			dh.close();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			LOG.error(new StringBuffer("获取数据信息异常，订单号：").append(orderid).append(
					"\n").append("执行语句：").append(sql).append("\n"));

			LOG.error(sql, e);

		} finally {

			return fo;

		}
	}

	private int update(String sql, Object... args) {

		int count = 0;

		DBHelper dh = DBHelper.getInstance();

		try {
			count = dh.update(sql, args);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			LOG.error(new StringBuffer("操作数据时异常").append(e.getMessage())
					.append("\n").append("执行语句：").append(sql).append("\n")
					.append("参数信息：").append(args));

			LOG.error(sql, e);

		}
		finally{
		dh.close();
			return count;
		}
	}

	/**
	 * 支付异步通知
	 */
	@Override
	public void autoPay(Map map) {
		// TODO Auto-generated method stub
		String sql = "{call addAutoPayNotice(?,?,?)}";

		Object[] args = new Object[3];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");

		args[2] = map.get("status");

		if (update(sql, args) > 0) {

			FlightOrder fo = getFlightOrder(map.get("orderNo").toString());

			IPayToApi aliPay = new PayToApi();

			PayEntity pe = new PayEntity();

			pe.setTot_trans_amt((new String().valueOf((int) (Double
					.parseDouble(fo.getOrderTotal().toString()) * 100))));

			pe.setOrderid(fo.getOrderNo().toString());

			pe.setBuyer_id(fo.getMemberNum().toString());

			pe.setSub_order_flag("N");

			pe.setSub_order_num(0);

			pe.setSeller_id(GlobalVariables.FLIGHT_SELLER_ID);

			pe.setOrder_CreateTime(fo.getBookDate().toString());

			pe.setNotify_url(PropertiesManager.getInstance().returnValue(
					"PAY_FLIGHT_NOTICE"));

			if (fo != null) {
				if (map.get("status").equals("T")) {
					pe.setOrder_desc(returnOrderDesc(
							fo.getOrderNo().toString(), "支付成功，提交预授权完成请求"));
					aliPay.YSQWC(pe);
				} else {
					pe.setOrder_desc(returnOrderDesc(
							fo.getOrderNo().toString(), "支付失败，预授权撤销请求"));
					aliPay.YSQCX(pe);
				}
			}
		}
	}

	// 行程单支付通知
	public void itinAutoPay(Map map) {

		String sql = "{call add_itineraryPay_notice(?,?,?,?)}";

		Object[] args = new Object[4];

		args[0] = map.get("service");

		args[1] = map.get("itineraryNo");

		args[2] = map.get("status");

		args[3] = "行程单支付通知";

		if (update(sql, args) > 0) {

			Itinerary itin = getItineray(map.get("itineraryNo").toString());

			IPayToApi aliPay = new PayToApi();

			PayEntity pe = new PayEntity();

			LOG.info("支付通知前" + JSONObject.fromObject(itin));

			pe.setTot_trans_amt((new String().valueOf((int) (Double
					.parseDouble(itin.getPayTotal().toString()) * 100))));

			pe.setOrderid(itin.getItineraryNo().toString());

			pe.setBuyer_id(itin.getMemberNo().toString());

			pe.setSub_order_flag("N");

			pe.setSub_order_num(0);

			pe.setSeller_id(GlobalVariables.FLIGHT_SELLER_ID);

			pe.setNotify_url(PropertiesManager.getInstance().returnValue(
					"PAY_FLIGHT_NOTICE"));
			if (itin != null) {
				if (map.get("status").equals("T")) {
					pe.setOrder_desc(returnOrderDesc(itin.getItineraryNo(),
							"行程单支付成功，提交预授权完成请求"));
					aliPay.YSQWC(pe);
				} else {
					pe.setOrder_desc(returnOrderDesc(itin.getItineraryNo(),
							"行程单支付失败，预授权撤销请求"));
					aliPay.YSQCX(pe);
				}
			}
		}
	}

	@Override
	public void riseAutoPay(Map map) {
		// TODO Auto-generated method stub
		// 预授权完成
		String sql = "{call addAutoPayNotice(?,?,?)}";

		Object[] args = new Object[3];

		args[0] = map.get("service");

		args[1] = map.get("orderNo");

		args[2] = map.get("status");

		if (update(sql, args) > 0) {

			FlightOrder fo = getFlightOrder(map.get("orderNo").toString());

			IPayToApi aliPay = new PayToApi();

			PayEntity pe = new PayEntity();

			pe.setTot_trans_amt((new String().valueOf((int) (Double
					.parseDouble(fo.getOrderTotal().toString()) * 100))));

			pe.setOrderid(fo.getOrderNo().toString());

			pe.setBuyer_id(fo.getMemberNum().toString());

			pe.setSub_order_flag("N");

			pe.setSub_order_num(0);

			pe.setSeller_id(GlobalVariables.FLIGHT_SELLER_ID);

			pe.setNotify_url(PropertiesManager.getInstance().returnValue(
					"PAY_FLIGHT_NOTICE"));
			if (fo != null) {
				if (map.get("status").equals("T")) {
					pe.setOrder_desc(returnOrderDesc(
							fo.getOrderNo().toString(), "升舱支付成功，提交预授权完成请求"));
					aliPay.YSQWC(pe);
				}
				if (map.get("status").equals("F")) {
					pe.setOrder_desc(returnOrderDesc(
							fo.getOrderNo().toString(), "升舱支付失败，预授权撤销请求"));
					aliPay.YSQCX(pe);
				}
			}
		}

	}

	@Override
	public void orderWaitCreate(Map map) {
		// TODO Auto-generated method stub
		String sql = "{call add_wait_order(?,?,?,?)}";

		StringBuffer desc_buffer = new StringBuffer("等待预订通知,");

		if (CommonUtil.isNotNullOrEmpty(map.get("Error")) == false) {
			desc_buffer.append("大编[").append(map.get("BigCode")).append("]")
					.append("OfficeNo：[").append(map.get("OfficeNo")).append(
							"]");
			Object[] args = new Object[4];

			args[0] = map.get("service");

			args[1] = map.get("orderNo");

			args[2] = map.get("PNR");

			args[3] = desc_buffer.toString();

			if (update(sql, args) > 0) {
				FlightOrder fo = getFlightOrder(map.get("orderNo").toString());
				String content = new StringBuffer(CommonUtil
						.returnShortDateTime(fo.getSdate().toString(),
								"yyyy-MM-dd")).append("从")
						.append(fo.getScity()).append("飞往").append(
								fo.getEcity()).append("的航班[").append(
								fo.getFlightNo()).append("]订位成功，请在30分钟内进行支付操作")
						.toString();

				int sendcode = new SmsSendService().sendSms(fo.getPhoneNum()
						.toString(), content, "等待预订短信通知");

			}
		} else {
			Object[] args = new Object[4];

			args[0] = map.get("service");

			args[1] = map.get("orderNo");

			args[2] = "0000";

			try {
				args[3] = new String(map.get("Error").toString().getBytes(
						"ISO-8859-1"), "GBK");
			} catch (UnsupportedEncodingException e) {
				args[3] = map.get("Error").toString();
			} finally {
				update(sql, args);
			}

		}
	}
	
	/**
	 * 单用户行程单
	 * @param fo
	 */
//	private void addPassengerItin(FlightOrder fo){
//		String[] passengers = fo.getPassengers().toString().split("\\|");
//		String[] ticketNos = fo.getTicketNo().toString().split("\\^");
//		String strPass=null,ticketNo=null;
//		String sqlProc="{call addOrderTicketItin(?,?,?,?,?,?,?,?,?)}";
//		String orderNo = fo.getOrderNo().toString().trim();
//		String pnrNo = fo.getPnrNo().toString().trim();
//		String memberNum = fo.getMemberNum().toString().trim();
//		String voyage = fo.getScity()+"—"+fo.getEcity();
//		Timestamp flightDate = fo.getArrTime();
//		Object[] args = new Object[9];
//		for (int i = 0; i < passengers.length; i++) {
//			strPass=passengers[i];
//			args[0] = orderNo;
//			args[1] = strPass.split("\\^")[0].toString().trim();//乘客姓名
//			args[2] = flightDate;	//起飞时间
//			args[3] = ticketNos[i];	//票号
//			args[4] = pnrNo;		//PNR编码
//			args[5] = 0;			//未申请过行程单
//			args[6] = 2;			//订单状态 出票
//			args[7] = memberNum;	//会员号
//			args[8] = voyage;
//			update(sqlProc, args);
//		}
//	}
	
}
